pub mod renderer;
pub mod framework;
pub mod background;
pub mod dinosaur;
pub mod obstruction;
pub mod camera;
pub mod util;
pub mod c_interfaces;

#[cfg(test)]
mod test;



use std::collections::HashMap;
use std::{sync::OnceLock, path::PathBuf};
use cgmath::Vector2;
use renderer::Texture;

pub static WIDTH: u32 = 1000;
pub static HEIGHT: u32 = 600;
pub static SCREEN_SIZE: Vector2<f64> = Vector2 {
    x: WIDTH as _, y: HEIGHT as _,
};

#[allow(non_snake_case)]
pub fn WORK_DIRECTORY() -> &'static PathBuf {
    static WORK_DIRECTORY: OnceLock<PathBuf> = OnceLock::new();
    WORK_DIRECTORY.get_or_init(|| {
        std::env::current_dir().unwrap()
    })
}

#[allow(non_snake_case)]
pub fn TEXTURES() -> &'static HashMap<String, Texture> {
    static TEXTURES: OnceLock<HashMap<String, Texture>> = OnceLock::new();
    TEXTURES.get_or_init(|| {
        let mut textures = HashMap::new();
        let texture_dir = WORK_DIRECTORY().join("assets/texture");
        let textures_to_load = vec![
            ("Bird1"        .to_string(), texture_dir.join("pterosaur/Bird1.png")),
            ("Bird2"        .to_string(), texture_dir.join("pterosaur/Bird2.png")),
            ("Cactus_BIG1"  .to_string(), texture_dir.join("cactus/Cactus_BIG1.png")),
            ("Cactus_BIG2"  .to_string(), texture_dir.join("cactus/Cactus_BIG2.png")),
            ("Cactus_MIX"   .to_string(), texture_dir.join("cactus/Cactus_MIX.png")),
            ("Cactus_SMALL1".to_string(), texture_dir.join("cactus/Cactus_SMALL1.png")),
            ("Cactus_SMALL2".to_string(), texture_dir.join("cactus/Cactus_SMALL2.png")),
            ("Cactus_SMALL3".to_string(), texture_dir.join("cactus/Cactus_SMALL3.png")),
            ("Meteorite"    .to_string(), texture_dir.join("meteorite/Meteorite.png")),
            ("Attack1"      .to_string(), texture_dir.join("dinosaur/Attack1.png")),
            ("Attack2"      .to_string(), texture_dir.join("dinosaur/Attack2.png")),
            ("Stand1"       .to_string(), texture_dir.join("dinosaur/Stand1.png")),
            ("Stand2"       .to_string(), texture_dir.join("dinosaur/Stand2.png")),
            ("Crouch1"      .to_string(), texture_dir.join("dinosaur/Crouch1.png")),
            ("Crouch2"      .to_string(), texture_dir.join("dinosaur/Crouch2.png")),
            ("Fail"         .to_string(), texture_dir.join("dinosaur/Fail.png")),
            ("Fireball"     .to_string(), texture_dir.join("dinosaur/Fireball.png")),
            ("Idle"         .to_string(), texture_dir.join("dinosaur/Idle.png")),
            ("Energy0"      .to_string(), texture_dir.join("ui/Energy0.png")),
            ("Energy1"      .to_string(), texture_dir.join("ui/Energy1.png")),
            ("Energy2"      .to_string(), texture_dir.join("ui/Energy2.png")),
            ("Energy3"      .to_string(), texture_dir.join("ui/Energy3.png")),
            ("Heart1"       .to_string(), texture_dir.join("ui/Heart1.png")),
            ("Heart2"       .to_string(), texture_dir.join("ui/Heart2.png")),
            ("Heart3"       .to_string(), texture_dir.join("ui/Heart3.png")),
            ("LAYER_CLOUD"  .to_string(), texture_dir.join("background/LAYER_CLOUD.png")),
            ("LAYER_GROUND" .to_string(), texture_dir.join("background/LAYER_GROUND.png")),
            ("LAYER_MOON"   .to_string(), texture_dir.join("background/LAYER_MOON.png")),
            ("LAYER_STAR"   .to_string(), texture_dir.join("background/LAYER_STAR.png")),
        ];

        for (name, path) in textures_to_load.into_iter() {
            textures.insert(
                name,
                Texture::from_file(path),
            );
        }

        textures
    })
}
